package com.edu.exam.entity.academic;

import com.edu.exam.enums.academic.AcademicYearStatus;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 学年实体类
 * 所属模块：F-07 基础数据管理模块
 * 对应数据库表：academic_year
 *
 * 管理学校教学年度的基本信息，包含学年的开始时间、结束时间、状态等属性。
 * 支持学年信息的验证、计算和状态管理。
 *
 * @author System
 * @version 1.0.0
 */
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "academic_year")
@Comment("学年表")
public class AcademicYear {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    /**
     * 学年代码，唯一标识符
     */
    @NotBlank(message = "学年代码不能为空")
    @Size(max = 20, message = "学年代码长度不能超过20个字符")
    @Column(name = "year_code", nullable = false, unique = true, length = 20)
    private String yearCode;

    /**
     * 学年名称
     */
    @NotBlank(message = "学年名称不能为空")
    @Size(max = 100, message = "学年名称长度不能超过100个字符")
    @Column(name = "year_name", nullable = false, length = 100)
    private String yearName;

    /**
     * 开始日期
     */
    @NotNull(message = "开始日期不能为空")
    @Column(name = "start_date", nullable = false)
    private LocalDate startDate;

    /**
     * 结束日期
     */
    @NotNull(message = "结束日期不能为空")
    @Column(name = "end_date", nullable = false)
    private LocalDate endDate;

    /**
     * 状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "year_status", nullable = false, length = 20)
    @Builder.Default
    private AcademicYearStatus yearStatus = AcademicYearStatus.PLANNING;

    /**
     * 描述信息
     */
    @Size(max = 500, message = "描述信息长度不能超过500个字符")
    @Column(name = "year_description", length = 500)
    private String yearDescription;

    /**
     * 总周数
     */
    @Column(name = "total_weeks")
    @Builder.Default
    private Integer totalWeeks = 0;

    /**
     * 教学周数
     */
    @Column(name = "teaching_weeks")
    @Builder.Default
    private Integer teachingWeeks = 0;

    /**
     * 考试周数
     */
    @Column(name = "exam_weeks")
    @Builder.Default
    private Integer examWeeks = 0;

    /**
     * 当前学年标识
     */
    @Column(name = "is_current_year")
    @Builder.Default
    private Boolean isCurrentYear = false;

    /**
     * 是否激活
     */
    @Column(name = "is_active")
    @Builder.Default
    private Boolean isActive = true;

    /**
     * 创建时间
     */
    @Column(name = "created_time", nullable = false, updatable = false)
    private LocalDateTime createdTime;

    /**
     * 更新时间
     */
    @Column(name = "updated_time", nullable = false)
    private LocalDateTime updatedTime;

    /**
     * 创建人
     */
    @Size(max = 50, message = "创建人长度不能超过50个字符")
    @Column(name = "created_by", nullable = false, length = 50)
    private String createdBy;

    /**
     * 更新人
     */
    @Size(max = 50, message = "更新人长度不能超过50个字符")
    @Column(name = "updated_by", length = 50)
    private String updatedBy;

    @PrePersist
    protected void onCreate() {
        LocalDateTime now = LocalDateTime.now();
        this.createdTime = now;
        this.updatedTime = now;
    }

    @PreUpdate
    protected void onUpdate() {
        this.updatedTime = LocalDateTime.now();
    }

    /**
     * 验证学年格式
     */
    public boolean validateYearFormat() {
        return yearCode != null && yearCode.matches("\\d{4}-\\d{4}");
    }

    /**
     * 计算持续天数
     */
    public long calculateDuration() {
        if (startDate == null || endDate == null) {
            return 0;
        }
        return startDate.until(endDate).getDays() + 1;
    }

    /**
     * 判断是否当前学年
     */
    public boolean isActiveYear() {
        LocalDate now = LocalDate.now();
        return !startDate.isAfter(now) && !endDate.isBefore(now);
    }
}